from PyQt5.QtGui import QIcon, QImage, QPainter
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMenu, QAction, QListWidget, QFileDialog

from GUI.Menu import Action
from GUI.Widget.Layer.Layer import ListWidget
from GUI.Widget.Canvas import ImageDialog


class ImageLayerList(ListWidget):
    # 默认类型
    layerDefaultType = 'pixmap'
    # 默认图标
    layerDefaultIcon = {
        'pixmap': QIcon(':/tool/pixmap.png'),
        'text': QIcon(':/tool/tool-text.png'),
        'shape': QIcon(':/tool/tool-shape.png')
    }

    # context
    context = None
    contextTargetItem = None    # content ListItem对象
    copiedItem = None   # 被复制的列表项目

    # 组件
    imageWindow = None  # 图像工作区窗体

    def __init__(self, parent):
        super().__init__(parent)
        self.imageWindow = parent.parent()
        # 定位
        # pos = layerPanel.geometry()
        # self.setGeometry(0, 0, pos.width(), pos.height())
        # content
        self.contextInit()
        # 信号
        self.currentItemChanged.connect(self.selectedLayerChangeSlot)
    
    def contextInit(self):
        # Content
        menu = QMenu(self)
        self.context = menu

        Act = self.__newAction("新建", menu)
        menu.addAction(Act)
        Act.func = self._newContext
        menu.newAct = Act

        deleteAct = self.__newAction("删除", menu)
        menu.addAction(deleteAct)
        deleteAct.func = self._removeContextLayer
        menu.deleteAct = deleteAct

        menu.addSeparator()

        showAct = self.__newAction("显示", menu)
        menu.addAction(showAct)
        showAct.func = self._showContextLayer
        menu.showAct = showAct

        hideAct = self.__newAction("隐藏", menu)
        menu.addAction(hideAct)
        hideAct.func = self._hideContextLayer
        menu.hideAct = hideAct

        menu.addSeparator()

        copyAct = self.__newAction("复制", menu)
        menu.addAction(copyAct)
        copyAct.func = self._copyContextLayer
        menu.copyAct = copyAct

        pasteAct = self.__newAction("粘贴", menu)
        menu.addAction(pasteAct)
        pasteAct.func = self._pasteContext
        menu.pasteAct = pasteAct

        Act = self.__newAction("保存为", menu)
        menu.addAction(Act)
        Act.func = self._saveAsContext
        menu.saveAsAct = Act

        Act = self.__newAction("预览", menu)
        menu.addAction(Act)
        Act.func = self.__previewContext
        menu.previewAct = Act

    def __newAction(self, name='', parent=None):
        return Action(name, parent, self.imageWindow.window)
    
    def contextMenuEvent(self, event):
        hitIndex = self.indexAt(event.pos()).row()
        if hitIndex > -1:
            item = self.item(hitIndex)  # 获取选择的Item
            self.contextTargetItem = item
            # 显示隐藏项目
            if item.show:
                self.context.showAct.setVisible(False)
                self.context.hideAct.setVisible(True)
            else:
                self.context.showAct.setVisible(True)
                self.context.hideAct.setVisible(False)

            # 显示复制选项
            self.context.copyAct.setVisible(True)
            # 显示删除选项
            self.context.deleteAct.setVisible(True)
            # 显示预览
            self.context.previewAct.setVisible(True)
        else:
            self.contextTargetItem = None
            # 隐藏删除选项
            self.context.deleteAct.setVisible(False)
            # 隐藏复制选项
            self.context.copyAct.setVisible(False)
            # 隐藏 显示隐藏 选项
            self.context.showAct.setVisible(False)
            self.context.hideAct.setVisible(False)
            # 隐藏预览
            self.context.previewAct.setVisible(False)

        # 是否显示粘贴选项
        if self.copiedItem:
            self.context.pasteAct.setVisible(True)
        else:
            self.context.pasteAct.setVisible(False)

        # 弹出
        self.context.popup(self.mapToGlobal(event.pos()))

    def _removeContextLayer(self):
        """
        移除当前 context 目标
        :return:
        """
        # 检查图层是否保存
        layer = self.contextTargetItem
        if layer.isEditing:
            layer.aboutSave()
            return
        if self.contextTargetItem:
            self.removeLayer(self.contextTargetItem)

    def _showContextLayer(self):
        """
        显示当前 context 目标
        :return:
        """
        if self.contextTargetItem:
            print('showAct')
            self.showLayer(self.contextTargetItem, True)

    def _hideContextLayer(self):
        """
        隐藏当前 context 目标
        :return:
        """
        layer = self.contextTargetItem
        if layer:
            # 检查图层是否保存
            if layer.isEditing:
                layer.aboutSave()
                return
            print('hideAct')
            self.showLayer(self.contextTargetItem, False)

    def _copyContextLayer(self):
        if self.contextTargetItem:
            if self.contextTargetItem.layerType == 'pixmap':
                self.copiedItem = self.contextTargetItem

    def _pasteContext(self):
        if self.copiedItem:
            self.imageWindow.addPixmapLayer(self.copiedItem.image, True)

    def _saveAsContext(self):
        layer = self.currentItem()
        layer.updateImage()
        image = layer.image
        fileName = QFileDialog.getSaveFileName(self, '保存图层', './imageLayer.png', 'Images (*.png *.xpm *.jpg)')
        if fileName[0] != '':
            image.save(fileName[0])
        layer.updatePixmap()

    def _newContext(self):
        """
        新建透明图像
        :return:
        """
        size = self.imageWindow.canvasSize
        if size:
            image = QImage(size, QImage.Format_ARGB32)
            image.fill(0x00ffffff)
            self.imageWindow.addPixmapLayer(image, False)

    def __previewContext(self):
        if self.contextTargetItem:
            pixmap = self.contextTargetItem.graphicsItem.pixmap()
            widget = ImageDialog(self.imageWindow.window, pixmap)
            widget.setWindowTitle(self.contextTargetItem.text())
            widget.move(400, 300)
            widget.show()
            # widget.update()
            # self.pr = widget

    def mousePressEvent(self, event):
        '''
        选择列表项目
        :param event:
        :return:
        '''
        if event.button() == Qt.LeftButton:
            # hitIndex = layerList.indexAt(event.pos()).row()
            # item = layerList.item(hitIndex)  # 获取选择的Item
            item = self.itemAt(event.pos())
            if item is not None:
                previous = self.previousItem
                if item != previous:
                    if previous:
                        previous.setSelected(False)
                    self.currentItemChanged.emit([item, previous])
                    self.previous = item
                    item.setSelected(True)
                    self.setCurrentItem(item)
            QListWidget.mousePressEvent(self, event)

    def dropEvent(self, event):
        """
        :param event: QDropEvent
        :return:
        """
        QListWidget.dropEvent(self, event)
        self.itemRowChanged.emit()

    def selectedLayerChangeSlot(self, arg):
        """
        :param arg: [current, previous]
        :return:
        由其他模块重写
        """
        # print(arg)
        window = self.imageWindow.window  # MainWindow
        tool = window.toolBar.currentTool
        print(tool.name, ':图层改变')
        # 禁用前图层所有 graphicsItem
        previous = arg[1]
        if previous:
            previous.graphicsItem.setEnabled(False)
            # 工具取消选择图层事件
            event = getattr(tool, 'toolFocusOffLayerEvent', None)
            if event:
                layer = previous
                if layer:
                    print(tool.name, '取消焦距', layer.text())
                    event(tool, layer)
        # 启用现图层所有 graphicsItem
        current = arg[0]
        if current:
            # 更新 图层混合模式 透明度显示
            self.imageWindow.updateLayerCompositionMode(current)
            self.imageWindow.updateLayerAlpha(current)

            current.graphicsItem.setEnabled(True)
            # 工具选择图层事件
            event = getattr(tool, 'toolFocusOnLayerEvent', None)
            if event:
                layer = current
                if layer:
                    print(tool.name, '焦距', layer.text())
                    event(tool, layer)


    def setSelectedLayer(self, item):
        """
        chose an item, but the previous item will be deselected
        :return:
        """
        if item:
            previous = self.previousItem
            if item != previous:
                item.setSelected(True)
                self.setCurrentItem(item)
                if previous:
                    previous.setSelected(False)
                self.previous = item
                self.selectedLayerChangeSlot([item, previous])
